<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1,2,3,'a','2',null,NaN,undefined,{a:1},true 10项
        var arr = [3,'a', 1, 2, 2, 3, '2', 3, null, NaN, null, NaN, undefined, {size:1}, undefined, true, {size:1}, true];
        // 方法一：利用splice方法去重
        // 说明：用双层for循环嵌套，用每一项与另外得其他项一一对比，若相同则删除后面的相同项
        function newArr(arr) {
            for(var i=0; i<arr.length; i++) {
                for(var j=i+1; j<arr.length; j++) {
                    if(arr[i] == arr[j]) {
                        arr.splice(j,1);
                        j--;
                    }
                }
            }
            return arr;
        }
        console.log(newArr(arr)); 

        // 0: 3
        // 1: "a"
        // 2: 1
        // 3: 2
        // 4: null
        // 5: NaN
        // 6: NaN
        // 7: {size: 1}
        // 8: {size: 1}
        // length: 9

        // 缺少：underfined ,true
        // 无法处理： NaN, {size:1} ,2 与 '2'

        // 方法二：indexOf
        // 说明：创建一个新数组，在新数组中利用indexOf方法判断数组中是否有相同值，无则返回-1，然后将该项push进去新数组
        function newArr2(arr) {
            var result =[];
            for(var i=0; i<arr.length; i++) {
                if(result.indexOf(arr[i]) == -1) {
                    result.push(arr[i])
                }
            }
            return result;
        }
        console.log(newArr2(arr))

        // 0: 3
        // 1: "a"
        // 2: 1
        // 3: 2
        // 4: "2"
        // 5: null
        // 6: NaN
        // 7: NaN
        // 8: undefined
        // 9: {size: 1}
        // 10: true
        // 11: {size: 1}
        // length: 12

        // 缺少： 无
        // 无法处理： NaN, {size:1}

        // 方法三：Set 与 Array.from
        // 说明：Set是ES6的新数据结构，类似于数组，但本身没有重复值，Array.from可以用于将两类对象转为真正的数组：类似数组对象，可遍历对象
        function newArr3(arr) {
            return Array.from(new Set(arr));
        }
        console.log(newArr3(arr))

        // 0: 3
        // 1: "a"
        // 2: 1
        // 3: 2
        // 4: "2"
        // 5: null
        // 6: NaN
        // 7: undefined
        // 8: {size: 1}
        // 9: true
        // 10: {size: 1}
        // 11: {}
        // 12: {}
        // length: 13

        // 缺少：无
        // 无法处理： {size:1} ，{}


        // 方法四：扩展运算符与Set
        // 说明：使用...简化了方法三的代码
        var newArr4 = [...new Set(arr)];
        console.log(newArr4);

        // 0: 3
        // 1: "a"
        // 2: 1
        // 3: 2
        // 4: "2"
        // 5: null
        // 6: NaN
        // 7: undefined
        // 8: {size: 1}
        // 9: true
        // 10: {size: 1}
        // length: 11
        
        // 缺少： 无
        // 无法处理： {a:1}

        // 方法五：利用对象属性去重
        // 说明：每次去原数组的元素，然后再对象中访问这个属性，在进行对比、
        Array.prototype.unique = function(){
            var temp = {};
            var newArr = [];
            for(var i=0; i < this.length; i++) {
                if(!temp.hasOwnProperty(this[i])) {
                    temp[this[i]] = this[i];
                    newArr.push(this[i])
                }
            }
            return newArr;
        }
        console.log(arr.unique());

        // 0: 3
        // 1: "a"
        // 2: 1
        // 3: 2
        // 4: null
        // 5: NaN
        // 6: undefined
        // 7: {size: 1}
        // 8: true
        // length: 9

        // 无法识别：无
        // 无法处理： '2' 与 2
        // 推荐使用

        // 方法六： sort排序
        // 说明：先判断是否为数组； 
        // 通过sort方法将排序后的数组保存在临时变量temp中，保存temp的第0项即为1，再通过for循环对比前后两项的值，不同则存入数组
        function newArr5(arr) {
            if(!Array.isArray(arr)) {
                console.log('type error!')
                return;
            }
            temp = arr.sort();
            var result = [temp[0]];
            for(var i =1; i<arr.length; i++) {
                if(temp[i] !== temp[i-1]) {
                    result.push(temp[i]);
                }
            }
            return result;
        }
        console.log(newArr5(arr));

        // 0: 1
        // 1: 2
        // 2: "2"
        // 3: 3
        // 4: NaN
        // 5: NaN
        // 6: {size: 1}
        // 7: {size: 1}
        // 8: "a"
        // 9: null
        // 10: true
        // 11: undefined
        // length: 12

        // 无法识别：无
        // 无法处理： NaN , {size:1}


    </script>
</body>
</html>